package com.jiaofamily.localad.sdk;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

import android.Manifest.permission;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;

import com.jiaofamily.localad.sdk.config.Config;
import com.jiaofamily.localad.sdk.obj.Extra;
import com.jiaofamily.localad.sdk.obj.Ration;
import com.jiaofamily.localad.sdk.util.LocalAdUtil;

public class LocalAdManager {
	private static final String TAG = LocalAdManager.class.getSimpleName();

	private WeakReference<Context> contextReference = null;
	private String key = null;

	Iterator<Ration> rollovers = null;
	Iterator<Ration> rollover_pri = null;
	private List<Ration> rationsList = null;
	private List<Ration> rationsList_pri = null;

	private Extra extra;

	private double totalWeight = 0.0D;

	public LocalAdManager(WeakReference<Context> contextReference, String key) {
		super();
		// TODO Auto-generated constructor stub
		Log.i(TAG, "Create AdManager");
		this.contextReference = contextReference;
		this.key = key;

	}

	public void fetchConfig() {
		parseExtra();
		parseRation();
	}

	private void parseExtra() {
		Extra extra = new Extra();
		extra.cycleTime = Config.DEFAULT_CYCLE_TIME;
		extra.transition = Config.DEFAULT_TRANSITION;
		extra.locationOn = Config.DEFAULT_LOCATION_ON;
		extra.bgRed = Config.DEFAULT_BG_RED;
		extra.bgGreen = Config.DEFAULT_BG_GREEN;
		extra.bgBlue = Config.DEFAULT_BG_BLUE;
		extra.bgAlpha = Config.DEFAULT_BG_ALPHA;
		extra.fgRed = Config.DEFAULT_FG_RED;
		extra.fgGreen = Config.DEFAULT_FG_GREEN;
		extra.fgBlue = Config.DEFAULT_FG_BLUE;
		extra.fgAlpha = Config.DEFAULT_FG_ALPHA;
		this.extra = extra;
	}

	public void parseRation() {
		// String language=getLanguage(this.contextReference.get());
		List<Ration> rationsList = new ArrayList<Ration>();
		List<Ration> rationsList_pri = new ArrayList<Ration>();

		Config.COUNT_SDK = Config.listRation.size();
		if (Config.COUNT_SDK > 0 && getLanguage(this.contextReference.get()).equals("zh")) {
			this.totalWeight = 0.0D;
			for (int i = 0; i < Config.COUNT_SDK; i++) {
				Ration ration = Config.listRation.get(i);
				if (ration.isEnabled) {
					this.totalWeight += ration.weight;
					rationsList.add(ration);
					rationsList_pri.add(ration);
				}
			}
			Config.COUNT_SDK = rationsList.size();
		} else {
			// only show admob
			Ration ration = new Ration();
			ration.name = Config.RATION_ADMOB_NAME;
			ration.weight = Config.RATION_ADMOB_WEIGHT;
			ration.type = LocalAdUtil.NETWORK_TYPE_ADMOB;

			switch (ration.type) {
			case LocalAdUtil.NETWORK_TYPE_ADMOB:
				ration.key = Config.RATION_ADMOB_KEY;
				break;
			}

			this.totalWeight = 100.0;
			rationsList.add(ration);
			rationsList_pri.add(ration);
			Config.COUNT_SDK = 1;
		}

		Collections.sort(rationsList);
		this.rationsList = rationsList;
		this.rollovers = this.rationsList.iterator();

		Collections.sort(rationsList_pri);
		this.rationsList_pri = rationsList_pri;
		this.rollover_pri = rationsList_pri.iterator();
	}

	private void addWeight(int network_type) {
		this.totalWeight++;
		if (this.totalWeight > 100) {
			this.totalWeight = 100;
		}
		for (int i = 0; i < this.rationsList.size(); i++) {
			if (network_type == this.rationsList.get(i).type) {
				Ration ration = this.rationsList.get(i);
				ration.weight++;
				if (ration.weight > 100) {
					ration.weight = 100;
				}
				this.rationsList.set(i, ration);
				Collections.sort(this.rationsList);
				this.rollovers = this.rationsList.iterator();

				Collections.sort(this.rationsList_pri);
				this.rollover_pri = this.rationsList_pri.iterator();
				
				break;
			}
		}
		
	}

	public void subWeight(int network_type) {
		this.totalWeight--;
		if (this.totalWeight < 0) {
			this.totalWeight = 0;
		}
		for (int i = 0; i < this.rationsList.size(); i++) {
			if (network_type == this.rationsList.get(i).type) {
				Ration ration = this.rationsList.get(i);
				ration.weight--;
				if (ration.weight < 0) {
					ration.weight = 0;
				}
				this.rationsList.set(i, ration);
				
				Collections.sort(this.rationsList);
				this.rollovers = this.rationsList.iterator();

				Collections.sort(this.rationsList_pri);
				this.rollover_pri = this.rationsList_pri.iterator();
				
				/*
				 * add weight to another biggest weight one
				 */
				if (network_type == this.rationsList.get(0).type) {
					addWeight(this.rationsList.get(1).type);
				}else {
					addWeight(this.rationsList.get(0).type);
				}
				break;
			}
		}
		
	}

	public Extra getExtra() {
		if (this.totalWeight <= 0.0D) {
			return null;
		}
		return this.extra;

	}

	public Ration getRation() {
		Random random = new Random();
		double r = random.nextDouble() * this.totalWeight;
		double s = 0.0D;

		Iterator<Ration> it = this.rationsList.iterator();
		Ration ration = null;
		while (it.hasNext()) {
			ration = it.next();
			if (ration.weight == 0) {
				it.remove();
				Config.COUNT_SDK = this.rationsList.size();
//				System.out.println("remove ration -" + ration.name
//						+ " rationList size=" + this.rationsList.size());
				if (this.rationsList.size() == 0) {
					ration = null;
					break;
				} else {
					continue;
				}
			} else {
				s += ration.weight;
				if (s >= r) {
					break;
				}
			}

		}
		return ration;
	}

	public Ration getRollover() {
		if (this.rollovers == null) {
			return null;
		}

		Ration ration = null;
		if (this.rollovers.hasNext()) {
			ration = this.rollovers.next();
		}
		return ration;
	}

	public void resetRollover() {
		this.rollovers = this.rationsList.iterator();
	}

	public void resetRollover_pri() {
		this.rollovers = this.rationsList.iterator();
		this.rollover_pri = this.rationsList_pri.iterator();
	}

	public Ration getRollover_pri() {
		int max = 100000000;
		if (this.rollover_pri == null) {
			return null;
		}

		Ration ration = null;
		Ration ration_pri = null;
		while (this.rollover_pri.hasNext()) {
			ration = this.rollover_pri.next();
			if (ration.priority >= max)
				continue;
			ration_pri = ration;
			max = ration.priority;
		}

		return ration_pri;
	}

	public Location getLocation() {
		if (this.contextReference == null) {
			return null;
		}

		Context context = this.contextReference.get();
		if (context == null) {
			return null;
		}

		Location location = null;
		LocationManager lm = (LocationManager) context
				.getSystemService(Context.LOCATION_SERVICE);
		if (context
				.checkCallingOrSelfPermission(permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
			location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
		} else if (context
				.checkCallingOrSelfPermission(permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
			location = lm
					.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
		}
		return location;
	}

	public String getLanguage(Context context) {
		String mUserLanguage = context.getResources().getConfiguration().locale
				.getLanguage();
		return mUserLanguage;
	}
}
